/***************************************************************************
 *   Copyright (C) 2005 by xihe						   *
 *   xihels@163.com							   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "pixmaps.h"
#include "Unit.h"

#define CLUSTER_FACE	10000
#define GROUP_FACE	10001

namespace 
{
    template<int size>
	inline Glib::RefPtr<Gdk::Pixbuf> createPix(int index, bool online)
	{
	    char buf[512];
	    if (online)
		snprintf(buf, 512, "%sface/%d.gif", GUnit::getImagePath(), index + 1);
	    else 
		snprintf(buf, 512, "%sface/%d-off.gif", GUnit::getImagePath(), index + 1);
	    return Gdk::Pixbuf::create_from_file(buf, size, size);
	}
    template<>
	inline Glib::RefPtr<Gdk::Pixbuf> createPix<-1>(int index, bool online)
	{
	    char buf[512];
	    if (online)
		snprintf(buf, 512, "%sface/%d.gif", GUnit::getImagePath(), index + 1);
	    else 
		snprintf(buf, 512, "%sface/%d-off.gif", GUnit::getImagePath(), index + 1);
	    return Gdk::Pixbuf::create_from_file(buf);
	}

    template<int size>
	Glib::RefPtr<Gdk::Pixbuf> doGetPix(int index, int status)
	{
	    static Glib::RefPtr<Gdk::Pixbuf> npixmap[100];
	    static Glib::RefPtr<Gdk::Pixbuf> opixmap[100];

	    if (index > 99 || index < 0)
		index = 0;

	    switch (status) {
		case QQ_FRIEND_STATUS_ONLINE:
		case QQ_FRIEND_STATUS_AWAY:
		    if (!npixmap[index]) {
			npixmap[index] = createPix<size>(index, true);
		    }
		    return npixmap[index];
		default:
		    if (!opixmap[index]) {
			opixmap[index] = createPix<size>(index, false);
		    }
		    return opixmap[index];

	    }
	}

    template<>
	Glib::RefPtr<Gdk::Pixbuf> doGetPix<-1>(int index, int status)
	{

	    static Glib::RefPtr<Gdk::Pixbuf> naPix = getPix("na.png");
	    static int naPixWidth = naPix->get_width();
	    static int naPixHeight = naPix->get_height();

	    static Glib::RefPtr<Gdk::Pixbuf> npixmap[100];
	    static Glib::RefPtr<Gdk::Pixbuf> apixmap[100];
	    static Glib::RefPtr<Gdk::Pixbuf> opixmap[100];

	    if (index > 100 || index < 0)
		index = 0;

	    switch (status) {
		case QQ_FRIEND_STATUS_ONLINE:
		    if (!npixmap[index]) {
			npixmap[index] = createPix<-1>(index, true);
		    }
		    return npixmap[index];
		case QQ_FRIEND_STATUS_AWAY:
		    if (!apixmap[index]){
			apixmap[index] = createPix<-1>(index, true);

			naPix->copy_area(0, 0,
				naPixWidth,
				naPixHeight,
				apixmap[index],
				apixmap[index]->get_width() - naPixWidth,
				apixmap[index]->get_height() - naPixHeight);
		    }
		    return apixmap[index];
		default:
		    if (!opixmap[index]) {
			opixmap[index] = createPix<-1>(index, false);
		    }
		    return opixmap[index];
	    }

	}

}

Glib::RefPtr<Gdk::Pixbuf> getClusterFace()
{
    static Glib::RefPtr<Gdk::Pixbuf> face = createPix<-1>(CLUSTER_FACE, true);
    return face;
}
Glib::RefPtr<Gdk::Pixbuf> getClusterFace22()
{
    static Glib::RefPtr<Gdk::Pixbuf> face = createPix<22>(CLUSTER_FACE, true);
    return face;
}
Glib::RefPtr<Gdk::Pixbuf> getClusterFace15()
{
    static Glib::RefPtr<Gdk::Pixbuf> face = createPix<15>(CLUSTER_FACE, true);
    return face;
}

Glib::RefPtr<Gdk::Pixbuf> getGroupFace()
{
    static Glib::RefPtr<Gdk::Pixbuf> face = createPix<-1>(GROUP_FACE, true);
    return face;
}
Glib::RefPtr<Gdk::Pixbuf> getGroupFace22()
{
    static Glib::RefPtr<Gdk::Pixbuf> face = createPix<22>(GROUP_FACE, true);
    return face;
}
Glib::RefPtr<Gdk::Pixbuf> getGroupFace15()
{
    static Glib::RefPtr<Gdk::Pixbuf> face = createPix<15>(GROUP_FACE, true);
    return face;
}


Glib::RefPtr<Gdk::Pixbuf> getPix22(int index, int status)
{
    return doGetPix<22>(index, status);
}

Glib::RefPtr<Gdk::Pixbuf> getPix15(int index, int status)
{
    return doGetPix<15>(index, status);
}

Glib::RefPtr<Gdk::Pixbuf> getPix(int index, int status)
{
    return doGetPix<-1>(index, status);
}

Gtk::Image* getSmil(int index)
{
    static SmileyMap smileys;

    if ((index < 0) || (index > (QQ_SMILEY_AMOUNT - 1))) {
	index = 0;
    }

    return Gtk::manage(new Gtk::Image(smileys.getSmil(index)));
}

Gtk::Image* getImage(const char* filename)
{
    char buf[512];
    snprintf(buf, 512, "%simage/%s", GUnit::getImagePath(), filename);
    return Gtk::manage(new Gtk::Image(buf));
}


Glib::RefPtr<Gdk::Pixbuf> getPix(const char* filename)
{
    char buf[512];
    snprintf(buf, 512, "%simage/%s", GUnit::getImagePath(), filename);
    return Gdk::Pixbuf::create_from_file(buf);
}

SmileyMap::SmileyMap()
{
    char buf[512];
    for (int i = 0; i < QQ_SMILEY_AMOUNT; i++) {
	snprintf(buf, 512, "%ssmiley/smiley_%d.gif", GUnit::getImagePath(), i);
	smil[i] = Gdk::PixbufAnimation::create_from_file(buf);
    }
}

const char* SmileyMap::smilarry[] = {
    "\\jy", "\\pz", "\\se", "\\fd", "\\dy",
    "\\ll", "\\hx", "\\bz", "\\shui", "\\dk", 
    "\\gg", "\\fn", "\\tp", "\\cy", "\\wx",
    "\\dd", "\\mn", "\\hl", "\\mamao", "\\qz", 
    "\\mm", "\\fw", "\\zhao", "\\tiao", "\\shan",
    "\\fad", "\\oh", "\\aiq", "\\bj", "\\zq", 
    "\\qsh", "\\bei", "\\xig", "\\mg", "\\dx",
    "\\wen", "\\xin", "\\xs", "\\dg", "\\lw",
    "\\xy", "\\duoy", "\\ty", "\\xr", "\\xixing",
    "\\yl", "\\qiang", "\\ruo", "\\nv", "\\nan", 
    "\\ng", "\\kuk", "\\feid", "\\zk", "\\tu",
    "\\jk", "\\lh", "\\hanx", "\\db", "\\zt",
    "\\maom", "\\xg", "\\yb", "\\gf", "\\fan",
    "\\yw", "\\hy", "\\dh", "\\sj", "\\yj",
    "\\ds", "\\ws", "\\bb", "\\tx", "\\ka",
    "\\by", "\\am", "\\jie", "\\kun", "\\fendou",
    "\\zhm", "\\yiw", "\\xu", "\\yun", "\\zhem",
    "\\shuai", "\\kl", "\\qiao", "\\zj", "\\qianc",
    "\\dp", "\\shd", "\\zhd", "\\dao", "\\yy", "\\shl"
};


int SmileyMap::getSmilIndex(const char* ch, int len, uint8_t& index) 
{
    index = 255;
    int j;
    bool ret;
    const char* shortcut;
    const char* msg;

    for (int i = 0; i < QQ_SMILEY_AMOUNT; i++) {
	shortcut = smilarry[i];
	msg = ch;
	ret = true;
	for (j = 0; j < len && *shortcut; j++, msg++, shortcut++) {
	    if (*msg != *shortcut) {
		ret = false;
		break;
	    }
	}
	if (ret && !*shortcut) {
	    index = i;
	    return j;
	}
    }
    return 0;
}


